#include "mapwindow.h"
#include "ui_mapwindow.h"
#include "common.h"

#include <QNetworkAccessManager>
#include <QJsonDocument>
#include <QJsonObject>
#include <QPixmap>
#include <QTouchEvent>
#include <QNetworkInterface>

#define MAX_ZOOM 18
#define MIN_ZOOM 3

MapWindow::MapWindow(QWidget *parent) : QWidget(parent),
                                        ui(new Ui::MapWindow)
{
    ui->setupUi(this);

    //QString localIp = getLocalIp();
    //qDebug() << "本机Ip地址：" << localIp;
    //updateCoordsByIp(localIp); // 根据本机Ip地址定位并更新地图

    updateMap();

    setupSearch(ui->lineEdit_cityName);

    // 设置触摸事件
    setAttribute(Qt::WA_AcceptTouchEvents);

    // 安装事件过滤器
    this->installEventFilter(this);
}

MapWindow::~MapWindow()
{
    delete ui;
}

// 获取本地Ip函数
QString MapWindow::getLocalIp() {
    foreach (const QHostAddress &address, QNetworkInterface::allAddresses()) {
        if (!address.isLoopback()) { // 不要回环地址
            return address.toString().remove("%.*"); // 去除接口标识符
        }
    }
    return "";
}

// 更新地图函数
void MapWindow::updateMap()
{
    int width = 500;
    int height = 300;

    QNetworkAccessManager *manager = new QNetworkAccessManager();
    QString mapURL = QString(MAP_URL).arg(MAP_AK).arg(width).arg(height).arg(this->zoom).arg(this->lng).arg(this->lat);

    this->reply = manager->get(QNetworkRequest(QUrl(mapURL)));

    file = new QFile();
    file->setFileName("./temp.png");
    file->open(QFile::WriteOnly);

    connect(reply, &QNetworkReply::readyRead, this, &MapWindow::readMapData);
    connect(reply, &QNetworkReply::finished, this, &MapWindow::showMap);
}

// 更新经纬度函数
void MapWindow::updateCoordsByIp(QString mapIp)
{
    QNetworkAccessManager *manager = new QNetworkAccessManager();
    QString mapURL = QString(MAP_URL_IP).arg(mapIp).arg(MAP_AK);

    auto dReply = manager->get(QNetworkRequest(QUrl(mapURL)));

    connect(manager, &QNetworkAccessManager::finished, this, [=]() {
        QJsonDocument doc = QJsonDocument::fromJson(dReply->readAll());
        QJsonObject obj = doc.object();

        //qDebug() << doc;

        QJsonObject point = obj["content"].toObject()["point"].toObject();
        QString newLng = point["x"].toString();
        QString newLat = point["y"].toString();

        if (!newLng.isEmpty() && !newLat.isEmpty())
        {
            this->lng = newLng;
            this->lat = newLat;
        }

        qDebug() << "Lng: " << this->lng << ", Lat" << this->lat;
        updateMap();
        dReply->deleteLater();
    });
}

// 更新经纬度函数
void MapWindow::updateCoordsByCityName(QString cityName)
{
    QNetworkAccessManager *manager = new QNetworkAccessManager(this);
    QString apiUrl = QString(MAP_URL_CITYNAME)
                        .arg(QString(QUrl::toPercentEncoding(cityName))).arg(MAP_AK);

    auto dReply = manager->get(QNetworkRequest(QUrl(apiUrl)));

    connect(manager, &QNetworkAccessManager::finished, this, [=]() {
        QJsonDocument doc = QJsonDocument::fromJson(dReply->readAll());
        QJsonObject obj = doc.object();

        //qDebug() << doc;

        if (obj["status"].toInt() == 0) { // 百度API状态码0表示成功
            QJsonObject location = obj["result"].toObject()["location"].toObject();

            QString newLng = QString::number(location["lng"].toDouble()); // 经度
            QString newLat = QString::number(location["lat"].toDouble()); // 纬度

            if (!newLng.isEmpty() && !newLat.isEmpty())
            {
                this->lng = newLng;
                this->lat = newLat;
            }

            qDebug() << "Lng: " << this->lng << ", Lat" << this->lat;
            updateMap();
        } else {
            qWarning() << "地理坐标检索失败";
        }
        dReply->deleteLater();
    });
}

// 拖动地图事件过滤器
bool MapWindow::eventFilter(QObject *watched, QEvent *event)
{
    if (watched == this)
    {
        QTouchEvent *touch = static_cast<QTouchEvent *>(event);
        switch (event->type())
        {
        case QEvent::MouseButtonPress: // 鼠标按下事件
            pres_flag = 1;

            last_point.setY(cursor().pos().y()); // 记录按下点的y坐标
            last_point.setX(cursor().pos().x()); // 记录按下点的x坐标
            break;
        case QEvent::MouseButtonRelease: // 鼠标松开事件
            rele_flag = 1;

            point.setY(cursor().pos().y()); // 记录按下点的y坐标
            point.setX(cursor().pos().x()); // 记录按下点的x坐标
            break;

        case QEvent::TouchBegin: // 触摸事件
            point.setY(touch->touchPoints().at(0).pos().y()); // 记录按下点的y坐标
            point.setX(touch->touchPoints().at(0).pos().x()); // 记录按下点的x坐标

            rele_flag = 1;
            pres_flag = 1;

            event->accept();
            break;

        default:
            break;
        }
    }

    int m_x;
    int m_y;
    double move_x;
    double move_y;
    if (pres_flag == 1 && rele_flag == 1)
    {
        pres_flag = 0;
        rele_flag = 0;
        if (event->type() == QEvent::TouchBegin) // 触摸
        {
            m_x = 400 - point.x();
            m_y = 240 - point.y();
        }
        else
        { // 鼠标
            m_x = point.x() - last_point.x();
            m_y = point.y() - last_point.y();
        }
        if (m_x > 10 || m_x < -10 || m_y > 10 || m_y < -10)
        {
            int m_zoom = zoom;
            // 计算需要偏移多少东经北纬
            move_x = m_x * 0.0000003 * (19 - m_zoom) * (19 - m_zoom) * (19 - m_zoom) * (19 - m_zoom);
            move_y = m_y * 0.0000003 * (19 - m_zoom) * (19 - m_zoom) * (19 - m_zoom) * (19 - m_zoom);
            double east = this->lng.toDouble();
            double north = this->lat.toDouble();
            east -= move_x;
            north += move_y;
            this->lng = QString::number(east);
            this->lat = QString::number(north);

            updateMap(); // 发送图片请求
        }
    }

    return QWidget::eventFilter(watched, event); // 将事件传递给父类
}

void MapWindow::setupSearch(QLineEdit *input) {
    // 连接输入框信号与槽函数
    connect(input, &QLineEdit::textChanged, this, &MapWindow::onTextChanged);
}

// 返回主页面按钮槽函数
void MapWindow::on_button_back_clicked()
{
    emit backSignal();
}

// 输入框文本变化槽函数
void MapWindow::onTextChanged(const QString &text)
{
    if(text.isEmpty()) {
        return;
    }

    updateCoordsByCityName(text);
}

// 展示图片槽函数
void MapWindow::showMap()
{
    file->close();

    QPixmap map = QPixmap("./temp.png");
    ui->label_map->setPixmap(map);
}

// 读取图片数据槽函数
void MapWindow::readMapData()
{
    file->write(reply->readAll());
}

// 放大地图按钮槽函数
void MapWindow::on_button_big_clicked()
{
    this->zoom++;
    if (zoom > MAX_ZOOM)
        this->zoom = MAX_ZOOM;

    qDebug() << "Current zoom: " << zoom;
    updateMap();
}

// 缩小地图按钮槽函数
void MapWindow::on_button_small_clicked()
{
    this->zoom--;
    if (zoom < MIN_ZOOM)
        this->zoom = MIN_ZOOM;

    qDebug() << "Current zoom: " << zoom;
    updateMap();
}
